#include "GraphicThread.hpp"

/********************************************//**
 * Creates an instance the class.
 *
 * Note that the thread is not ran, you need to call
 * Start() for it.
 ***********************************************/
se::Graphics::GraphicThread::GraphicThread():
	m_screen(NULL),
	m_requestSettingsUpdate(false){
	System::ExceptionSafeThread::SetFunctor(boost::bind<void>(&GraphicThread::RunThread,this));
}

/********************************************//**
 * Delete the instance the class.
 *
 * Please ensure that the thread is closed before
 * deleting.
 * \see 
 ***********************************************/
se::Graphics::GraphicThread::~GraphicThread(){

}

/********************************************//**
 * Add a sprite to render.
 * 
 * The sprite is copied, with as image the one
 * Updated at the time at is called.
 ***********************************************/
void se::Graphics::GraphicThread::Push(se::Graphics::AnimatedSprite& s){
	s.Update();
	Drawable d(s.renderFunction,(AnimatedSpritePOD&)s);
	m_drawablesSwap.ProducerGet()->
		insert(std::pair<uint16_t,Drawable>
		       (s.Layer,d));
}

void se::Graphics::GraphicThread::Swap(){
	m_screen->clear();
	std::multimap<uint16_t,Drawable> *m = m_drawablesSwap.ProducerGet();
	std::multimap<uint16_t,Drawable>::iterator iter;
	for(iter = m->begin();iter!=m->end();++iter){
		iter->second.renderFunction(*m_screen,iter->second);
	}
	m->clear();
	m_screen->display();
	//m_drawablesSwap.ProducerSwap();
}

void se::Graphics::GraphicThread::SetRenderWindow(sf::RenderWindow& renderWindow){
	m_screen = &renderWindow;
	m_screen->setActive(false);
}

void se::Graphics::GraphicThread::RunThread(){
	bool exitNeeded = false;
	if(!m_screen){
		SE_LOGC(EXCEPTION_UNHANDLED,"No screen was set for the graphic thread. Exiting Graphics thread.");
		return;
	}
	m_screen->setActive(true);
	while(!exitNeeded){
		/*
		m_drawablesSwap.ConsumerSwap();
		m_screen->clear();
		std::multimap<uint16_t,Drawable> *m = m_drawablesSwap.ConsumerGet();
		std::multimap<uint16_t,Drawable>::iterator iter;
		for(iter = m->begin();iter!=m->end();++iter){
			iter->second.renderFunction(*m_screen,iter->second);
		}
		m->clear();
		m_screen->display();
		*/
		if(GetInterruptRequested()) exitNeeded = true;
	}
}

void se::Graphics::GraphicThread::SetFunctor(boost::function<void()> t){
	System::ExceptionSafeThread::SetFunctor(t);
}
